﻿package l1j.taki;

import java.lang.reflect.Constructor;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
import java.util.logging.Level;

import l1j.server.server.GeneralThreadPool;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.model.L1World;
import l1j.server.server.model.L1Location;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_MapID;
import l1j.server.server.serverpackets.S_OtherCharPacks;
import l1j.server.server.serverpackets.S_OwnCharPack;
import l1j.server.server.serverpackets.S_RemoveObject;
import l1j.server.server.serverpackets.S_Weather;
import l1j.server.server.templates.L1Npc;


public class PledgeCave extends TimerTask {
	
	private static Logger _log = Logger.getLogger(PledgeCave.class.getName());
	
	private Timer _timeHandler = new Timer(true);	
	
	private boolean _isOver = false;
	
	// 巨龍谷開始時間(1/2秒)
	private int _startTime = 0;
	
	private int _start = 0;
	
	private static PledgeCave _instance;
	
	public static PledgeCave getStart() {
		if (_instance == null) {
			_instance = new PledgeCave();
		}
		return _instance;
	}
	
	public void startPledgeCave(){
		PledgeCave.getStart();
	}
	
	private PledgeCave() {
		// 開始執行此時間軸
		_timeHandler.schedule(this, 500, 500);
		// 交由線程工廠 處理
		GeneralThreadPool.getInstance().execute(this);
	}

	@Override
	public void run() {	
		if (_isOver){
			clear();
		}
		if(_start >= 1){
		_startTime ++;
		switch (_startTime) {
		case 30*2:// 10秒時
		L1World.getInstance().broadcastServerMessage("\\fT【隱匿的巨龍谷】傳來一陣龍吟聲...");
			break;
		case 40*2:// 10秒時
			L1World.getInstance().broadcastServerMessage("\\fW【隱匿的巨龍谷】將於五分鐘後開啟。");
			break;		
		case 600:// 開啟(時間軸開始第5分鐘)
			spawnCave();
			break;
		case 86300:// 5分鐘後關閉(時間軸開始第3小時55分鐘)
			L1World.getInstance().broadcastServerMessage("\\fW【隱匿的巨龍谷】將於五分鐘後關閉。");
			break;
		case 86400:// 關閉(時間軸開始第4小時)
			_isOver = true;
			break;
			}
		}
	}
	
	public void BossGone() {
        _start = 2;
	}
	private void clear() {
		_startTime = 0;
		_start = 0;
		_isOver = false;
		L1World.getInstance().broadcastServerMessage("\\fY【隱匿的巨龍谷】關閉了。");
		for (L1Object obj : L1World.getInstance().getAllNpcs()) {
			if (obj instanceof L1NpcInstance) {
				L1NpcInstance Cavenpc = (L1NpcInstance) obj;
				if (Cavenpc.getNpcId()== 900002) {
					Cavenpc.deleteMe();
				}
			}
		}
		for(L1PcInstance pc : L1World.getInstance().getAllPlayers()){
			if (pc.getMapId() == 1002){
				if (pc.isDead()){
					restartPlayer(pc,32616,32782,(short)4);
				}else{
					L1Teleport.teleport(pc,33442,32797,(short)4,5,true);
				}	
			}
		}
	}

	private void spawnCave() {
		L1Location Cave = null;
		L1Location Cave_loc = null;
		Cave = new L1Location(32985, 32631, 1002);
		Cave_loc = new L1Location(32736, 32803, 52);
		L1World.getInstance().broadcastServerMessage("\\fT隱匿的巨龍谷已於【奇岩城堡】開啟!");
		createCave(Cave.getX(), Cave.getY(), (short) Cave.getMapId(), Cave_loc.getX(), Cave_loc.getY(), (short) Cave_loc.getMapId());
		createCave(Cave_loc.getX(), Cave_loc.getY(), (short) Cave_loc.getMapId(), Cave.getX(), Cave.getY(), (short) Cave.getMapId());
	}

	private void createCave(int x, int y, short mapId, int to_x, int to_y, short to_mapId) {
		try {
			L1Npc l1npc = NpcTable.getInstance().getTemplate(900002);

			if (l1npc == null) {
				return;
			}

			String s = l1npc.getImpl();
			Constructor<?> constructor = Class.forName("l1j.server.server.model.Instance." + s + "Instance").getConstructors()[0];
			Object aobj[] = { l1npc };
			L1NpcInstance npc = (L1NpcInstance) constructor.newInstance(aobj);

			npc.setId(IdFactory.getInstance().nextId());
			npc.setX(x);
			npc.setY(y);
			npc.setMap(mapId);
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(0);

			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);

			Teleport teleport = new Teleport(npc, to_x, to_y, to_mapId);
			GeneralThreadPool.getInstance().execute(teleport);
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}
	
	public void restartPlayer(L1PcInstance pc, int locx, int locy, short mapid){//移除玩家
		pc.removeAllKnownObjects();
		pc.broadcastPacket(new S_RemoveObject(pc));
		pc.setCurrentHp(pc.getLevel());
		pc.set_food(40);
		pc.setDead(false);
		pc.setStatus(0);
		L1World.getInstance().moveVisibleObject(pc, mapid);
		pc.setX(locx);
		pc.setY(locy);
		pc.setMap((short) mapid);
		pc.sendPackets(new S_MapID(pc.getMapId(), pc.getMap().isUnderwater()));
		pc.broadcastPacket(new S_OtherCharPacks(pc));
		pc.sendPackets(new S_OwnCharPack(pc));
		pc.sendPackets(new S_CharVisualUpdate(pc));
		pc.startHpRegeneration();
		pc.startMpRegeneration();
		pc.sendPackets(new S_Weather(L1World.getInstance().getWeather()));
		if (pc.getHellTime() > 0) {
			pc.beginHell(false);
		}
	}

	class Teleport implements Runnable {
		private L1NpcInstance _npc = null;

		private int _to_x = 0;
		private int _to_y = 0;
		private short _to_mapId = 0;

		public Teleport(L1NpcInstance npc, int to_x, int to_y, short to_mapId) {
			_npc = npc;
			_to_x = to_x;
			_to_y = to_y;
			_to_mapId = to_mapId;
		}

		public void run() {
			try {
				Thread.sleep(1000);
				for (;;) {
					if (_npc._destroyed) {
						return;
					}

					for (L1Object obj : L1World.getInstance().getVisiblePoint(_npc.getLocation(), 1)) {
						if (obj instanceof L1PcInstance) {
							L1PcInstance target = (L1PcInstance) obj;
							L1Location tmp_loc = new L1Location(_to_x, _to_y, _to_mapId);
							L1Location rnd_loc = tmp_loc.randomLocation(1, 5, false);
							L1Teleport.teleport(target, rnd_loc.getX(), rnd_loc.getY(), (short) rnd_loc.getMapId(), target.getHeading(), true);
						}
					}
					Thread.sleep(1000);
				}
			} catch (Exception e) {
				_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			}
		}
	}
}